package utils

// 导入依赖
import (
	"errors"
	"github.com/dgrijalva/jwt-go" // JWT 标准库
	"time"
)

// 定义签名密钥（实际项目应从环境变量读取）
var jwtSecret = []byte("JWT_SECRET") // ⚠️ 生产环境需替换为安全密钥

// 自定义声明结构体（嵌入标准声明）
type Claims struct {
	UserID             uint   `json:"user_id"` // 自定义用户ID字段
	Role               string `json:"role"`    // 自定义角色字段
	jwt.StandardClaims        // 嵌入标准字段（过期时间等）
}

// 生成 JWT Token
func GenerateToken(userID uint, role string) (string, error) {
	//设置声明内容
	claims := Claims{
		UserID: userID, // 注入用户标识
		Role:   role,   // 注入角色信息
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: time.Now().Add(24 * time.Hour).Unix(), // 24小时有效期
			Issuer:    "library-system",                      // 签发者标识
		},
	}

	// 创建签名令牌
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

	// 生成完整令牌字符串
	return token.SignedString(jwtSecret)
}

// 验证并解析 Token 的函数
func ParseToken(tokenString string) (*Claims, error) {
	token, err := jwt.ParseWithClaims(
		tokenString,
		&Claims{},
		func(token *jwt.Token) (interface{}, error) {
			return jwtSecret, nil
		},
	)

	// 第一步：立即处理错误
	if err != nil {
		// 细化错误类型处理
		if ve, ok := err.(*jwt.ValidationError); ok {
			if ve.Errors&jwt.ValidationErrorMalformed != 0 {
				return nil, errors.New("无效的令牌格式")
			} else if ve.Errors&(jwt.ValidationErrorExpired|jwt.ValidationErrorNotValidYet) != 0 {
				return nil, errors.New("令牌已过期或未生效")
			} else {
				return nil, errors.New("令牌验证失败")
			}
		}
		return nil, errors.New("无法处理令牌")
	}

	// 第二步：确保 token 非空且有效
	if token == nil || !token.Valid {
		return nil, errors.New("无效的令牌状态")
	}

	// 第三步：安全地进行类型断言
	if claims, ok := token.Claims.(*Claims); ok {
		return claims, nil
	}

	return nil, errors.New("无法解析令牌声明")
}
